<template>
  <el-drawer v-model="drawerVisible" size="50%" :close-on-click-modal="false" :before-close="handleClose"
    :show-close="false" destroy-on-close>
    <template #header>
      <div class="flex items-center justify-between w-full">
        <div class="flex items-center">
          <el-button link @click="handleClose" class="mr-2">
            <el-icon>
              <Close />
            </el-icon>
          </el-button>
          <span class="text-lg font-medium">
            {{ dialogType === 'add' ? 'Add Role' : 'Modify Role' }}
          </span>
        </div>
        <div class="flex gap-2">
          <el-button @click="handleClose">Cancel</el-button>
          <el-button type="primary" @click="submitForm">Submit</el-button>
        </div>
      </div>
    </template>

    <div class="drawer-content p-6">
      <el-form ref="formRef" :model="form" :rules="rules" label-width="180px" label-position="left">
        <el-form-item label="Role name:" prop="name" required>
          <el-input v-model="form.name" placeholder="Please enter" :maxlength="100" :show-word-limit="true" />
        </el-form-item>

        <el-form-item label="Organization Type:" prop="organizationType" required>
          <div class="flex gap-4">
            <el-radio-group v-model="form.organizationType">
              <el-radio :value="2">Distributor</el-radio>
              <el-radio :value="1">Installer</el-radio>
            </el-radio-group>
          </div>
        </el-form-item>

        <el-form-item label="Authority Type:" prop="authorityType" required>
          <div class="flex gap-4">
            <el-checkbox-group v-model="form.authorityType">
              <el-checkbox :value="'Web'">Web</el-checkbox>
              <el-checkbox :value="'App'">App</el-checkbox>
            </el-checkbox-group>
          </div>
        </el-form-item>

        <el-form-item label="Note:" prop="note">
          <el-input v-model="form.note" type="textarea" :rows="4" placeholder="Please enter" :maxlength="200"
            :show-word-limit="true" />
        </el-form-item>

        <!-- Web Permissions Section -->
        <template v-if="form.authorityType.includes('Web') || form.authorityType.includes('0')">
          <el-form-item label="Web Permissions:" prop="webPermissions" class="w-full">
            <div class="permissions-search mb-4 w-full">
              <el-input v-model="permissionSearch" placeholder="Please enter" :prefix-icon="Search" clearable
                class="w-full" />
            </div>
          </el-form-item>

          <div class="permissions-container w-full">
            <div class="select-all-bar">
              <el-checkbox v-model="selectAll" @change="handleSelectAll">Select All</el-checkbox>
            </div>
            <!-- 权限树 -->
            <div class="permission-tree-wrapper">
              <el-tree
                ref="permissionTree"
                :data="menuTreeData"
                :props="treeProps"
                show-checkbox
                node-key="id"
                :filter-node-method="filterNode"
                class="w-full permission-tree"
                @check="handleTreeCheck"
              />
            </div>
          </div>
        </template>
      </el-form>
    </div>
  </el-drawer>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, nextTick, onMounted } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import { Search, Close } from "@element-plus/icons-vue";
import { roleApi } from "@/api/authority";
import { filterMenus } from "@/utils/menuFilter";
import { logger } from "@/utils/logger";

const props = defineProps({
  visible: {
    type: Boolean,
    default: false
  },
  formData: {
    type: Object,
    default: () => ({})
  },
  dialogType: {
    type: String,
    default: "add" // 'add' or 'edit'
  }
});

const emit = defineEmits(["update:visible", "submit-success"]);

// 表单实例引用
const formRef = ref<FormInstance>();
const drawerVisible = ref(props.visible);
const permissionSearch = ref("");
const selectAll = ref(false);
const permissionTree = ref<any>(null);

// 表单数据
const form = reactive({
  name: "",
  organizationType: 2, // Distributor=2, Installer=1
  authorityType: ["App"] as string[], // 默认选择 App（文本）
  note: "",
  updateUser: "system@example.com",
  permissions: {},
  menuIdList: [] as (string | number)[] // 菜单权限ID列表
});

// 菜单树数据与属性
const menuTreeData = ref<any[]>([]);
// 增加 disabled 字段映射，便于“全选置灰”
const treeProps = { children: "children", label: "name", disabled: "disabled" } as const;

// 根据搜索关键字过滤权限树（按 name 字段）
const filterNode = (value: string, data: any) => {
  if (!value) return true;
  return String(data.name || data.label || "")
    .toLowerCase()
    .includes(value.toLowerCase());
};

// 监听搜索关键字变化，实时过滤树
watch(permissionSearch, val => {
  permissionTree.value?.filter(val);
});

// 加载菜单树（从后端动态获取），并统一节点 id 类型为 string
const loadMenuTree = async () => {
  try {
    const res = await roleApi.getAddQuery(); // GET sys/menu/select
    const raw = Array.isArray(res.data) ? res.data : [];
    
    // 应用菜单过滤
    const filteredRaw = filterMenus(raw);
    
    const normalizeIds = (nodes: any[]) => {
      const walk = (arr: any[]) => (arr || []).forEach(n => {
        n.id = String(n.id);
        if (n.children && n.children.length) walk(n.children);
      });
      walk(nodes);
      return nodes;
    };
    menuTreeData.value = normalizeIds(filteredRaw);
  } catch (e) {
    menuTreeData.value = [];
    logger.error("加载菜单树失败", e);
  }
};

// 编辑态：根据角色ID勾选已有菜单，优化回填逻辑避免过度选中
const checkRoleMenusIfEdit = async () => {
  const id = (props.formData as any)?.id;
  if (!id || props.dialogType !== "edit") return;
  try {
    const res = await roleApi.getById(String(id));
    const menuIdList: any[] = res?.data?.menuIdList || [];
    nextTick(() => {
      // 过滤回填数据：只设置存在于当前菜单树中的叶子节点
      const allLeafIds = getLeafIds(menuTreeData.value);
      const validLeafIds = menuIdList
        .map((x:any)=>String(x))
        .filter(id => allLeafIds.includes(id));
      
      console.log('回填权限 - 原始数据:', menuIdList);
      console.log('回填权限 - 有效叶子节点:', validLeafIds);
      
      permissionTree.value?.setCheckedKeys(validLeafIds);
      // 同步计算选中状态
      handleTreeCheck();
    });
  } catch (e) {
    logger.error("加载角色详情失败", e);
  }
};

// 初始化：加载菜单树
onMounted(async () => {
  await loadMenuTree();
  await checkRoleMenusIfEdit();
});

// 监听组织类型变化：切换时清空选择
watch(() => form.organizationType, () => {
  nextTick(() => permissionTree.value?.setCheckedKeys([]));
});

// 计算所有叶子节点ID
const getLeafIds = (nodes: any[]): string[] => {
  const ids: string[] = [];
  const walk = (arr: any[]) => arr.forEach(n => {
    if (n.children && n.children.length) walk(n.children); else ids.push(String(n.id));
  });
  walk(nodes || []);
  return ids;
};

// 勾选变化：只提交完全选中的节点，避免权限过度分配
const handleTreeCheck = () => {
  if (!permissionTree.value) return;
  try {
    // 只保存完全选中的节点，不包含半选中的父节点
    const checked = (permissionTree.value.getCheckedKeys() || []).map((x: any) => String(x));
    form.menuIdList = checked;

    // 全选判断：基于完全选中的节点与叶子节点比较
    const allLeafIds = getLeafIds(menuTreeData.value);
    selectAll.value = allLeafIds.length > 0 && checked.length >= allLeafIds.length;
  } catch (error) {
    logger.error('权限树选择处理失败:', error);
  }
};

// 统计叶子节点数量
const getLeafCount = (nodes: any[]): number => {
  let count = 0;
  const walk = (arr: any[]) => {
    arr.forEach((n) => {
      if (n.children && n.children.length) walk(n.children);
      else count += 1;
    });
  };
  walk(nodes || []);
  return count;
};

// 全选锁定标记
const grantAll = ref(false);

// 递归设置节点禁用/启用
const setDisabled = (nodes: any[], disabled: boolean) => {
  const walk = (arr: any[]) => (arr || []).forEach(n => {
    n.disabled = disabled;
    if (n.children && n.children.length) walk(n.children);
  });
  walk(nodes);
};

// 全选/全不选（全选时置灰锁定）
const handleSelectAll = (val: boolean) => {
  if (!permissionTree.value) return;
  if (val) {
    const allIds = getAllNodeIds(menuTreeData.value);
    permissionTree.value.setCheckedKeys(allIds);
    grantAll.value = true;
    setDisabled(menuTreeData.value, true);
  } else {
      permissionTree.value.setCheckedKeys([]);
      grantAll.value = false;
      setDisabled(menuTreeData.value, false);
  }
  handleTreeCheck();
};

const getAllNodeIds = (nodes: any[]): any[] => {
  const ids: any[] = [];
  const walk = (arr: any[]) => {
    arr.forEach((n) => {
      ids.push(n.id);
      if (n.children && n.children.length) walk(n.children);
    });
  };
  walk(nodes || []);
  return ids;
};


// Validation rules
const rules = reactive<FormRules>({
  name: [
    { required: true, message: "Please enter role name", trigger: "blur" },
    {
      max: 100,
      message: "Role name cannot exceed 100 characters",
      trigger: "blur"
    }
  ],
  organizationType: [
    {
      required: true,
      message: "Please select organization type",
      trigger: "change"
    }
  ],
  authorityType: [
    {
      validator: (rule: any, value: any, callback: any) => {
        if (!value || value.length === 0) {
          callback(new Error('Please select at least one authority type'));
        } else {
          callback();
        }
      },
      trigger: "change"
    }
  ],
  note: [
    {
      max: 200,
      message: "Note cannot exceed 200 characters",
      trigger: "blur"
    }
  ]
});

// 监听可见性：父传入 visible 改变时同步抽屉显隐
watch(
  () => props.visible,
  val => {
    drawerVisible.value = val;
  }
);

// 监听抽屉可见性：同步回父组件
watch(
  () => drawerVisible.value,
  val => {
    emit("update:visible", val);
  }
);

// 监听父组件传入的表单数据：进入编辑态时回填
watch(
  () => props.formData,
  val => {
    // 先重置表单到初始状态
    Object.assign(form, {
      name: "",
      organizationType: 0, // 默认选择经销商 (0:分销商, 1:安装商)
      authorityType: ["1"], // 默认选择App (0:Web, 1:App)
      note: "",
      updateUser: "system@example.com",
      permissions: {},
      menuIdList: []
    });

    // 重置搜索和选择状态
    permissionSearch.value = "";
    selectAll.value = false;

    // 重置权限树选择
    nextTick(() => {
      if (permissionTree.value) {
        permissionTree.value.setCheckedKeys([]);
      }
    });

    if (Object.keys(val).length > 0) {
      // 合并表单数据，并将 authorityType 规范为文本数组 ["Web","App"]
      const toTextArray = (input: any): string[] => {
        let items: string[] = [];
        if (Array.isArray(input)) {
          input.forEach((it) => {
            if (typeof it === 'string') items.push(...it.split(',').map(s => s.trim()));
            else items.push(String(it));
          });
        } else if (typeof input === 'string') {
          items = input.split(',').map(s => s.trim());
        } else if (input != null) {
          items = [String(input)];
        }
        items = items.map(v => (v === '0' ? 'Web' : v === '1' ? 'App' : v))
                       .filter(v => v === 'Web' || v === 'App');
        return Array.from(new Set(items));
      };

      Object.assign(form, {
        ...val,
        authorityType: toTextArray((val as any).authorityType)
      });

      // 如果提供了权限数据，更新树选择
      nextTick(() => {
        checkRoleMenusIfEdit();
      });
    }
  },
  { immediate: true, deep: true }
);

// 监听 authorityType：若不包含 Web，则清空树与已选
watch(
  () => form.authorityType,
  () => {
    nextTick(() => {
      const hasWeb = form.authorityType.includes("Web") || form.authorityType.includes("0");
      if (!hasWeb && permissionTree.value) {
        permissionTree.value.setCheckedKeys([]);
        selectAll.value = false;
        form.menuIdList = [];
      }
    });
  }
);

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return;

  await formRef.value.validate((valid, fields) => {
    if (valid) {
      // Form validation passed, submit data
      // 统一并去重 authorityType，避免累计，并保持 0,1 顺序
      let cleanedAuthority = '';
      
      // 强制转换为数组处理
      const authorityArray = Array.isArray(form.authorityType) ? form.authorityType : [form.authorityType];
      const mappedValues = authorityArray.map((v: any) => {
        if (v === 'Web') return '0';
        if (v === 'App') return '1';
        return String(v);
      });
      cleanedAuthority = Array.from(new Set(mappedValues)).sort().join(',');

      // 只提交完全选中的节点，避免权限过度分配
      const safeMenuIdList = (permissionTree.value?.getCheckedKeys() || []).map((x:any)=>String(x));

      const payload = {
        ...form,
        authorityType: cleanedAuthority,
        // 只提交完全选中的节点
        menuIdList: safeMenuIdList,
        // Flag to distinguish add and edit operations
        isAdd: props.dialogType === "add"
      };

      // 调试日志：查看提交内容
      logger.dev('[Role] 提交数据:', payload);

      emit("submit-success", payload);
    }
  });
};

// Handle drawer close
const handleClose = () => {
  drawerVisible.value = false;
  // 关闭时重置表单数据
  Object.assign(form, {
    name: "",
    organizationType: 2, // Distributor=2, Installer=1
    authorityType: ["App"], // 默认选择 App（文本）
    note: "",
    updateUser: "system@example.com",
    permissions: {},
    menuIdList: []
  });
  permissionSearch.value = "";
  selectAll.value = false;
  if (permissionTree.value) {
    permissionTree.value.setCheckedKeys([]);
  }
};
</script>

<style lang="scss" scoped>
.drawer-content {
  height: calc(100% - 60px);
  overflow-y: auto;
}

.permissions-container {
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  overflow: hidden;
  background-color: #fff;
}

.select-all-bar {
  background-color: #f5f7fa;
  padding: 10px 12px;
  border-bottom: 1px solid #e4e7ed;
  position: sticky;
  top: 0;
  z-index: 1;
}

.permission-tree-wrapper {
  max-height: 400px;
  overflow-y: auto;
  padding: 8px 12px;
}



:deep(.el-tree-node__content) {
  height: 30px;
}

:deep(.el-tree-node__label) {
  font-size: 13px;
}

:deep(.el-checkbox__label) {
  font-weight: normal;
}

/* 更清晰的层级缩进与展开图标间距 */
:deep(.el-tree-node__expand-icon) {
  margin-right: 6px;
}

/* 子节点区域缩进与紧凑布局 */
:deep(.el-tree-node__children) {
  margin-left: 16px;
}

/* 去除默认 hover 背景，保持简洁 */
:deep(.el-tree-node__content:hover) {
  background-color: transparent;
}

.w-full {
  width: 100%;
}
</style>
